{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 程序说明\n",
    "时间：2016年11月16日\n",
    "\n",
    "说明：该程序是一个包含两个隐藏层的神经网络，程序会保存每轮训练的acc和loss，并且绘制它们。\n",
    "\n",
    "数据集：MNIST"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.加载keras模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "import numpy as np\n",
    "np.random.seed(1337)  # for reproducibility"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import keras\n",
    "from keras.datasets import mnist\n",
    "from keras.models import Sequential\n",
    "from keras.layers.core import Dense, Dropout, Activation\n",
    "from keras.optimizers import SGD, Adam, RMSprop\n",
    "from keras.utils import np_utils\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 写一个LossHistory类，保存loss和acc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class LossHistory(keras.callbacks.Callback):\n",
    "    def on_train_begin(self, logs={}):\n",
    "        self.losses = {'batch':[], 'epoch':[]}\n",
    "        self.accuracy = {'batch':[], 'epoch':[]}\n",
    "        self.val_loss = {'batch':[], 'epoch':[]}\n",
    "        self.val_acc = {'batch':[], 'epoch':[]}\n",
    "\n",
    "    def on_batch_end(self, batch, logs={}):\n",
    "        self.losses['batch'].append(logs.get('loss'))\n",
    "        self.accuracy['batch'].append(logs.get('acc'))\n",
    "        self.val_loss['batch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['batch'].append(logs.get('val_acc'))\n",
    "        \n",
    "    def on_epoch_end(self, batch, logs={}):\n",
    "        self.losses['epoch'].append(logs.get('loss'))\n",
    "        self.accuracy['epoch'].append(logs.get('acc'))\n",
    "        self.val_loss['epoch'].append(logs.get('val_loss'))\n",
    "        self.val_acc['epoch'].append(logs.get('val_acc'))\n",
    "        \n",
    "    def loss_plot(self, loss_type):\n",
    "        iters = range(len(self.losses[loss_type]))\n",
    "        plt.figure()\n",
    "        # acc\n",
    "        plt.plot(iters, self.accuracy[loss_type], 'r', label='train acc')\n",
    "        # loss\n",
    "        plt.plot(iters, self.losses[loss_type], 'g', label='train loss')\n",
    "        if loss_type == 'epoch':\n",
    "            # val_acc\n",
    "            plt.plot(iters, self.val_acc[loss_type], 'b', label='val acc')\n",
    "            # val_loss\n",
    "            plt.plot(iters, self.val_loss[loss_type], 'k', label='val loss')\n",
    "        plt.grid(True)\n",
    "        plt.xlabel(loss_type)\n",
    "        plt.ylabel('acc-loss')\n",
    "        plt.legend(loc=\"upper right\")\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.变量初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "batch_size = 128 \n",
    "nb_classes = 10\n",
    "nb_epoch = 20"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.准备数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "60000 train samples\n",
      "10000 test samples\n"
     ]
    }
   ],
   "source": [
    "# the data, shuffled and split between train and test sets\n",
    "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
    "\n",
    "X_train = X_train.reshape(60000, 784)\n",
    "X_test = X_test.reshape(10000, 784)\n",
    "X_train = X_train.astype('float32')\n",
    "X_test = X_test.astype('float32')\n",
    "X_train /= 255\n",
    "X_test /= 255\n",
    "print(X_train.shape[0], 'train samples')\n",
    "print(X_test.shape[0], 'test samples')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 转换类标号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# convert class vectors to binary class matrices\n",
    "Y_train = np_utils.to_categorical(y_train, nb_classes)\n",
    "Y_test = np_utils.to_categorical(y_test, nb_classes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.建立模型\n",
    "### 使用Sequential（）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "model = Sequential()\n",
    "model.add(Dense(512, input_shape=(784,)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dropout(0.2))\n",
    "model.add(Dense(512))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Dropout(0.2))\n",
    "model.add(Dense(10))\n",
    "model.add(Activation('softmax'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 打印模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense_4 (Dense)              (None, 512)               401920    \n",
      "_________________________________________________________________\n",
      "activation_4 (Activation)    (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dropout_3 (Dropout)          (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dense_5 (Dense)              (None, 512)               262656    \n",
      "_________________________________________________________________\n",
      "activation_5 (Activation)    (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dropout_4 (Dropout)          (None, 512)               0         \n",
      "_________________________________________________________________\n",
      "dense_6 (Dense)              (None, 10)                5130      \n",
      "_________________________________________________________________\n",
      "activation_6 (Activation)    (None, 10)                0         \n",
      "=================================================================\n",
      "Total params: 669,706\n",
      "Trainable params: 669,706\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.训练与评估\n",
    "### 编译模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "model.compile(loss='categorical_crossentropy',\n",
    "              optimizer=RMSprop(),\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 创建一个实例history"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "history = LossHistory()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 迭代训练（注意这个地方要加入callbacks）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 60000 samples, validate on 10000 samples\n",
      "Epoch 1/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.2432 - acc: 0.9252 - val_loss: 0.1089 - val_acc: 0.9664\n",
      "Epoch 2/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.1010 - acc: 0.9695 - val_loss: 0.0898 - val_acc: 0.9735\n",
      "Epoch 3/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0758 - acc: 0.9768 - val_loss: 0.0794 - val_acc: 0.9756\n",
      "Epoch 4/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0612 - acc: 0.9819 - val_loss: 0.0989 - val_acc: 0.9737\n",
      "Epoch 5/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0506 - acc: 0.9855 - val_loss: 0.0830 - val_acc: 0.9784\n",
      "Epoch 6/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0444 - acc: 0.9870 - val_loss: 0.0807 - val_acc: 0.9808\n",
      "Epoch 7/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0399 - acc: 0.9885 - val_loss: 0.0717 - val_acc: 0.9826\n",
      "Epoch 8/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0344 - acc: 0.9899 - val_loss: 0.0852 - val_acc: 0.9826\n",
      "Epoch 9/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0312 - acc: 0.9908 - val_loss: 0.0927 - val_acc: 0.9811\n",
      "Epoch 10/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0286 - acc: 0.9919 - val_loss: 0.0989 - val_acc: 0.9818\n",
      "Epoch 11/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0249 - acc: 0.9931 - val_loss: 0.0877 - val_acc: 0.9832\n",
      "Epoch 12/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0246 - acc: 0.9930 - val_loss: 0.0896 - val_acc: 0.9834\n",
      "Epoch 13/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0232 - acc: 0.9938 - val_loss: 0.1026 - val_acc: 0.9826\n",
      "Epoch 14/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0253 - acc: 0.9934 - val_loss: 0.0878 - val_acc: 0.9830\n",
      "Epoch 15/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0207 - acc: 0.9942 - val_loss: 0.1063 - val_acc: 0.9809\n",
      "Epoch 16/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0195 - acc: 0.9945 - val_loss: 0.1035 - val_acc: 0.9821\n",
      "Epoch 17/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0183 - acc: 0.9950 - val_loss: 0.1086 - val_acc: 0.9831\n",
      "Epoch 18/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0198 - acc: 0.9949 - val_loss: 0.1027 - val_acc: 0.9831\n",
      "Epoch 19/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0153 - acc: 0.9958 - val_loss: 0.1091 - val_acc: 0.9834\n",
      "Epoch 20/20\n",
      "60000/60000 [==============================] - 2s - loss: 0.0174 - acc: 0.9957 - val_loss: 0.1207 - val_acc: 0.9828\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f45e4784510>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(X_train, Y_train,\n",
    "            batch_size=batch_size, nb_epoch=nb_epoch,\n",
    "            verbose=1, \n",
    "            validation_data=(X_test, Y_test),\n",
    "            callbacks=[history])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模型评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test score: 0.120702062227\n",
      "Test accuracy: 0.9828\n"
     ]
    }
   ],
   "source": [
    "score = model.evaluate(X_test, Y_test, verbose=0)\n",
    "print('Test score:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 绘制acc-loss曲线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nrkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f45e47846d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "history.loss_plot('epoch')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  },
  "ssap_exp_config": {
   "error_alert": "Error Occurs!",
   "initial": [],
   "max_iteration": 1000,
   "recv_id": "",
   "running": [],
   "summary": [],
   "version": "1.1.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
